package com.gopay.scheduler.job;

import com.gopay.common.constants.trans.GatewaySource;
import com.gopay.common.constants.trans.GatewayVersion;
import com.gopay.common.constants.trans.TxnStaCode;
import com.gopay.common.constants.txncd.IntTxnCd;
import com.gopay.common.cps.dao.order.CpsGeneralMainOrderQueryDAO;
import com.gopay.common.domain.cps.CpsGenMainOrder;
import com.gopay.common.domain.pg.PgGenOrderTransDtl;
import com.gopay.common.exception.GopayException;
import com.gopay.common.gateway.manager.PgGeneralOrderTransDtlQueryManager;
import com.gopay.common.order.dao.CommonQueryDAO;
import com.gopay.common.util.DateUtils;
import com.gopay.remote.cps.notify.order.MerNotifyOrderRemoteService;
import com.gopay.remote.order.MainOrderField;
import com.gopay.remote.order.MainOrderUpdateRemoteService;
import com.gopay.scheduler.GopayBaseJob;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 付款到银行00700和提现00800，<br />
 * 一阶段没记账且没有控制台审批流的订单且payorder表的cust_audit_time非空且为当前时间3小时之前，<br />
 * 增加定时任务将订单状态置为20001-作废。<br />
 * lx 2017-7-31 15:32:49 生产bug 7 期
 */
public class ModifyOrderStatePayTypeOrderCleanJob extends GopayBaseJob {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Resource(name = "commonQueryDAO")
    private CommonQueryDAO commonQueryDAO;

    @Resource(name = "cpsGeneralMainOrderDAO")
    private CpsGeneralMainOrderQueryDAO cpsGeneralMainOrderDAO;

    @Resource(name = "cpsGeneralMainOrderOperClient")
    private MainOrderUpdateRemoteService cpsGeneralMainOrderOperClient;

    @Resource(name = "merOrderNotifyClient")
    private MerNotifyOrderRemoteService merOrderNotifyClient;

    @Resource(name="pgGeneralOrderTransDtlQueryManager")
    private PgGeneralOrderTransDtlQueryManager pgGeneralOrderTransDtlQueryManager;

//    @Resource(name = "fundCpsOrderDao")
//    private FundCpsOrderDao fundCpsOrderDao;

    @Override
    protected void doJobInternal() {
        logger.info("------- 修改00700&00800 web审批流完成超过3小时,未开启console审批流未做账 订单状态为20001 start -------");
        modifyOrderStatus(getOrdersByTime());
    }

    private void modifyOrderStatus(List<CpsGenMainOrder> list) {
        for (CpsGenMainOrder order : list) {
            {
                String orderId = order.getGopayOrderId();
                CpsGenMainOrder mainOrder = cpsGeneralMainOrderDAO.findByGopayOrderId(orderId);

                try {
                    Map<MainOrderField, String> map = new HashMap<>();
                    Date date = new Date();
                    map.put(MainOrderField.TXN_STA_CD, "20001");
                    map.put(MainOrderField.TRAN_FINISH_TIME, DateUtils.format(date));
                    map.put(MainOrderField.LAST_UPDATE_TIME, DateUtils.format(date));
                    if (StringUtils.isBlank(mainOrder.getErrMsg())) {
                        map.put(MainOrderField.ERR_MSG, "订单超时");//超过3小时未处理
                    }

                    cpsGeneralMainOrderOperClient.updateMany(mainOrder.getGopayOrderId(), map);

                    //发送商户后台通知  add by fanghw 20170923
                    if(GatewaySource.GATEWAY_SOURCE_01.value.equals(mainOrder.getGatewaySource())&&
                            IntTxnCd._00700.value.equals(mainOrder.getGopayIntTxnCd())){
                        sendMerNotify(orderId);
                    }


                    //同步修改基金订单状态，代码未测试，暂时屏蔽 TODO wangdong 20170816
//                    String fundGopayOrderId = mainOrder.getRelevanceGopayOrderId();
//                    if (StringUtils.isNotBlank(fundGopayOrderId)){
//                        CpsGenMainOrder mainOrder02012 = cpsGeneralMainOrderDAO.findByGopayOrderId(fundGopayOrderId);
//                        if(mainOrder02012!=null && IntTxnCd._02012.value.equals(mainOrder02012.getGopayIntTxnCd())){
//                            Map<MainOrderField, String> map02012 = new HashMap<>();
//                            map02012.put(MainOrderField.TXN_STA_CD, "20001");
//                            map02012.put(MainOrderField.TRAN_FINISH_TIME, DateUtils.format(date));
//                            map02012.put(MainOrderField.LAST_UPDATE_TIME, DateUtils.format(date));
//                            if (StringUtils.isBlank(mainOrder02012.getErrMsg())) {
//                                map02012.put(MainOrderField.ERR_MSG, "订单超时");//超过3小时未处理
//                            }
//                            cpsGeneralMainOrderOperClient.updateMany(mainOrder02012.getRelevanceGopayOrderId(), map02012);
//                            //修改基金订单
//                            //获取02012基金订单
//                            FundGopayCpsGenOrder fundGopayOrder = fundCpsOrderDao.getFundGopayOrder(fundGopayOrderId);
//                            if (fundGopayOrder!=null && IntTxnCd._02012.value.equals(fundGopayOrder.getGopayIntTxnCd())){
//                                //TODO 需要增加插入数据
//                                fundCpsOrderDao.updateFundCpsMainOrderStateByGopayOrderId(fundGopayOrderId,FundSettleStatusEnum.PAY_FAILURE.getValue());
//                            }
//                        }
//                    }
                } catch (GopayException e) {
                    logger.error("修改订单状态异常:{}", e);
                } catch (Exception e) {
                    logger.error("修改订单状态异常:{}", e);
                }
            }
        }
    }

    private List<CpsGenMainOrder> getOrdersByTime() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.HOUR_OF_DAY, -3); //获取3小时前
        Date dateStartTime = calendar.getTime();
        calendar.add(Calendar.HOUR_OF_DAY, -51);//两天零3小时前（2*24+3）
        Date dateEndTime = calendar.getTime();
        calendar.add(Calendar.HOUR_OF_DAY, -3-24*30);//30天内创建的订单
        Date dateMainOrderEndTime = calendar.getTime();
        String startTime = sdf.format(dateStartTime);
        String endTime = sdf.format(dateEndTime);
        String endMainOrderTime = sdf.format(dateMainOrderEndTime);
        Map<String, Object> map = new HashMap<>();
        map.put("startTime", startTime);
        map.put("endTime", endTime);
        map.put("endMainOrderTime", endMainOrderTime);
        StringBuffer sb = new StringBuffer();
        sb.append(" select distinct gopay_order_id, cust_audit_time ");
        sb.append(" from ");
        sb.append(" (select t.gopay_order_id, p.cust_audit_time ");
        sb.append(" from cps_gen_main_order t left join cps_gen_pay_order p ");
        sb.append(" on t.gopay_order_id = p.gopay_order_id ");
        sb.append(" left join acps_acct_trans_dtl d on t.gopay_order_id = d.gopay_order_id ");
        sb.append(" where 1 = 1 ");
        sb.append(" and d.gopay_order_id is null ");
        sb.append(" and p.cust_audit_time is not null ");
        sb.append(" and p.cust_audit_time >= to_date(:endTime,'yyyy-mm-dd hh24:mi:ss')  ");
        sb.append(" and p.cust_audit_time < to_date(:startTime,'yyyy-mm-dd hh24:mi:ss') ");
        sb.append(" and t.txn_sta_cd = 30000 ");
        sb.append(" and t.gopay_txn_tm  >= to_date(:endMainOrderTime,'yyyy-mm-dd hh24:mi:ss') "); // 查询主订单范围30天内的
        sb.append(" and t.gopay_txn_tm  < to_date(:startTime,'yyyy-mm-dd hh24:mi:ss')");
        sb.append(" and t.gopay_int_txn_cd in ('00700', '00800') ");
        sb.append(" and t.accounting_point is null ");
        sb.append(" union all ");
        sb.append(" select t.gopay_order_id, p.cust_audit_time ");
        sb.append(" from cps_gen_main_order t left join cps_gen_pay_order p ");
        sb.append(" on t.gopay_order_id = p.gopay_order_id ");
        sb.append(" left join acps_acct_trans_dtl d on t.gopay_order_id = d.gopay_order_id ");
        sb.append(" where 1 = 1 ");
        sb.append(" and d.gopay_order_id is null ");
        sb.append(" and p.cust_audit_time is not null ");
        sb.append(" and p.cust_audit_time >= to_date(:endTime,'yyyy-mm-dd hh24:mi:ss')  ");
        sb.append(" and p.cust_audit_time < to_date(:startTime,'yyyy-mm-dd hh24:mi:ss') ");
        sb.append(" and t.accounting_point = '1' ");//记账点为1  记账详情为空
        sb.append(" and t.txn_sta_cd = 30000 ");
        sb.append(" and t.gopay_int_txn_cd in ('00700', '00800') ");
        sb.append(" and t.gopay_txn_tm  >= to_date(:endMainOrderTime,'yyyy-mm-dd hh24:mi:ss') "); // 查询主订单范围30天内的
        sb.append(" and t.gopay_txn_tm  < to_date(:startTime,'yyyy-mm-dd hh24:mi:ss')) ");
        sb.append(" t0 left join WF_APPR_VIEW v on ( t0.gopay_order_id = v.target_id and v.approval_id=3 and v.target_id is null )");

       /* sb.append(" where gopay_order_id not in "); //排除 approval_id = 3 的订单
        sb.append(" (select v.target_id ");
        sb.append(" from WF_APPR_VIEW v ");
        sb.append(" where v.approval_id = 3 ");
        sb.append(" and v.created_ts >= to_date(:endMainOrderTime,'yyyy-mm-dd hh24:mi:ss') ");
        sb.append(" and v.created_ts < to_date(:startTime,'yyyy-mm-dd hh24:mi:ss') ) ");
        sb.append(" order by cust_audit_time ");*/

        List<Object[]> list = commonQueryDAO.findBySql(sb.toString(), map);
        return buildOrderListBySQL(list);
    }

    private List<CpsGenMainOrder> buildOrderListBySQL(List<Object[]> list) {
        List<CpsGenMainOrder> orderList = new ArrayList<>();
        for (Object[] obj : list) {
            CpsGenMainOrder order = new CpsGenMainOrder();
            order.setGopayOrderId(obj[0].toString());
            orderList.add(order);
        }
        return orderList;
    }

    /**
     * 发送商户后台通知
     * @param gopayOrderId
     */
    private void sendMerNotify(String gopayOrderId){
        try{
            CpsGenMainOrder main = cpsGeneralMainOrderDAO.findByGopayOrderId(gopayOrderId);
            if(!(main.getTxnStaCd()>= TxnStaCode.TXN_STA_CD_20000.value&&main.getTxnStaCd()<TxnStaCode.TXN_STA_CD_30000.value)){
                //进行中不发送商户后台通知
                return;
            }

            if(!IntTxnCd._00700.value.equals(main.getGopayIntTxnCd())){
                return;
            }

            if(!GatewaySource.GATEWAY_SOURCE_01.value.equals(main.getGatewaySource())){
                return;
            }

            PgGenOrderTransDtl pgTransDtl = pgGeneralOrderTransDtlQueryManager.get(main.getTransDtlSq());
            if(pgTransDtl != null && (GatewayVersion.V_1_1.getValue().equals(pgTransDtl.getGatewayVersion())
                    || GatewayVersion.V_1_2.getValue().equals(pgTransDtl.getGatewayVersion()))) {
                logger.info(String.format("开始发送商户后台通知，订单号=%s，订单状态=%s",gopayOrderId,main.getTxnStaCd()));

                merOrderNotifyClient.addNotify(main.getGopayOrderId(), false, "101");
            }

        }catch(Exception e){
            logger.error("发送商户后台通知异常，订单号="+gopayOrderId,e);
        }
    }

}
